package com.pray.server;

import com.pray.protocol.RpcRequest;
import com.pray.protocol.RpcResponse;
import com.pray.rpc.RpcRequestBody;
import com.pray.rpc.RpcResponseBody;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.HashMap;

/**
 * RpcServerWorker
 *
 * @author 春江花朝秋月夜
 * @since 2024/1/8 20:55
 */
public class RpcServerWorker implements Runnable {
    private Socket socket;
    private HashMap<String, Object> registeredService;

    public RpcServerWorker(Socket handleSocket, HashMap<String, Object> registeredService) {
        this.socket = handleSocket;
        this.registeredService = registeredService;
    }

    /**
     *
     */
    @Override
    public void run() {
        try {
            ObjectInputStream objectInputStream=new ObjectInputStream(socket.getInputStream());
            ObjectOutputStream objectOutputStream=new ObjectOutputStream(socket.getOutputStream());

            //1:客户端层面
            RpcRequest rpcRequest= (RpcRequest) objectInputStream.readObject();
            if (rpcRequest.getHeader().equals("rpc-framework")){
                byte[] body= rpcRequest.getBody();
                ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(body);
                ObjectInputStream objectInputStream1=new ObjectInputStream(byteArrayInputStream);
                RpcRequestBody rpcRequestBody= (RpcRequestBody) objectInputStream1.readObject();

                //调用服务
                Object service=registeredService.get(rpcRequestBody.getInterfaceName());
                Method method=service.getClass().getMethod(rpcRequestBody.getMethodName());
                Object returnObject=method.invoke(service,rpcRequestBody.getParameters());

                //1：将返回体编码成bytes[]
                RpcResponseBody rpcResponseBody=RpcResponseBody.builder()
                        .returnObject(returnObject)
                        .build();
                ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
                ObjectOutputStream outputStream=new ObjectOutputStream(byteArrayOutputStream);
                outputStream.writeObject(rpcResponseBody);
                byte[] bytes=byteArrayOutputStream.toByteArray();

                //2:返回
                RpcResponse rpcResponse=RpcResponse.builder()
                        .header("rpc-framework")
                        .body(bytes)
                        .build();
                //3:发送客户端

                objectOutputStream.writeObject(rpcResponse);
                objectOutputStream.flush();
            }
        } catch (IOException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException |
                 InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
}
